package chatServer;

import java.awt.EventQueue;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import javax.swing.JMenu;

/**
 * @author william orem
 *
 */
public class ServerGui {

	static ServerSocket serverSocket = null;
	static int port = 4444;
	static double ver = 1.5;
	boolean listening = true;
	ConversDB db = new ConversDB();
	private JFrame frame;
	JTextArea textArea;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ServerGui window = new ServerGui();
					window.frame.setVisible(true);
					
					
				} catch (Exception e) {
					System.err.println("Could not start");

				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public ServerGui() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	/**
	 * 
	 */
	private void initialize() {
		
		frame = new JFrame("ChatServer Version "+ver);
		frame.setBounds(100, 100, 650, 500);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JMenuBar menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);
		
		redirectSystemStreams();
		
		final SwingWorker<String, Void> worker = new SwingWorker<String,Void>(){
			@Override
			public String doInBackground(){ textArea.append("ChatServer " + ver + " started at "+serverSocket.getInetAddress()+" on port " + port+"\n");
				while (listening)		
					try {
						new ChatServerThread(serverSocket.accept(), db,true).start();
					} catch (IOException e) {
						textArea.append("Error on connection: "+e.getCause()+"\n");
					}
				return new String("done");
			}
			@Override
		    public void done() {
				try {
					serverSocket.close();
				} catch (IOException e1) {
					textArea.append("error closing socket\n");
				}
				textArea.append("Saving DB\n");
				db.saveState();
	
		    }
		};
		
		JMenu mnNewMenu = new JMenu("Menu");
		menuBar.add(mnNewMenu);
		
		
		JMenuItem mntmStart = new JMenuItem("Start");
		mnNewMenu.add(mntmStart);
		
		JMenuItem mntmStop = new JMenuItem("Stop");
		mnNewMenu.add(mntmStop);
		
		JMenuItem mntmShowMessageLog = new JMenuItem("Show Message Log");
		mntmShowMessageLog.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				LogWindow dialog = new LogWindow(db,0);
				dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
				dialog.setVisible(true);
			}
		});
		
		JMenuItem mntmUserlist = new JMenuItem("UserList");
		mntmUserlist.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				LogWindow dialog = new LogWindow(db,1);
				dialog.setTitle("Userlist");
				dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
				dialog.setVisible(true);
			}
		});
		mnNewMenu.add(mntmUserlist);
		mnNewMenu.add(mntmShowMessageLog);
		mntmStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				worker.cancel(true);
			}
		});
		mntmStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					serverSocket = new ServerSocket(4444);
				} catch (IOException e) {
					textArea.append("Could not listen on port: " + port+"\n");
				}
				worker.execute();
			}
		});
		frame.getContentPane().setLayout(null);
		
		textArea = new JTextArea();
		textArea.setBounds(10, 11, 614, 419);
		JScrollPane scrollPane = new JScrollPane(textArea);
		scrollPane.setBounds(10, 11, 614, 419);
		frame.getContentPane().add(scrollPane);
	}
	
	private void updateTextArea(final String text) {
		  SwingUtilities.invokeLater(new Runnable() {
		    public void run() {
		      textArea.append(text);
		    }
		  });
		}
		 
	private void redirectSystemStreams() {
		  OutputStream out = new OutputStream() {
		    @Override
		    public void write(int b) throws IOException {
		      updateTextArea(String.valueOf((char) b));
		    }
		 
		    @Override
		    public void write(byte[] b, int off, int len) throws IOException {
		      updateTextArea(new String(b, off, len));
		    }
		 
		    @Override
		    public void write(byte[] b) throws IOException {
		      write(b, 0, b.length);
		    }
		  };
		 
		  System.setOut(new PrintStream(out, true));
		  System.setErr(new PrintStream(out, true));
		}
}
